package com.atguigu.config;

import com.atguigu.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * bean 生命周期
 *      bean创建---初始化---销毁的课程
 * 容器管理bean的生命周期：
 * 我们可以自定义初始化和销毁方法，容器在bean进行到当前生命周期的时候调用我们自定义的初始化和销毁
 *
 * 构造(对象创建)
 *      单实例：在容器启动的时候创建对象
 *      多实例：在每次获取的时候创建对象
 *
 * BeanPostProcessor.postProcessBeforeInitialization
 * 初始化：
 *      对象创建完成时，并赋值好，调用初始化方法
 * BeanPostProcessor.postProcessAfterInitialization
 *
 *
 *   遍历得到容器中所有的BeanPostProcessor 挨个执行beforeInitialization
 *      一但返回null，跳出for循环，不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
 *
 * BeanPostProcessor原理
 *populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) //给bean属性赋值
 * initializeBean
 * {
 *wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);前面
 * invokeInitMethods(beanName, wrappedBean, mbd); 执行自定义初始化
 *  applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);后边
 *  }
 *销毁:
 *      容器销毁
 * 1、指定初始化和销毁方法
 *      通过在@Bean中init-method和destory-method
 * 2、通过Bean实现InitializingBean(定义初始化逻辑)
 *          DisposableBean(定义销毁逻辑)
 *
 * 3、可以使用JSR250
 *          @PostConstruct: 在bean创建完后并且属性赋值完成，来执行初始化方法
 *          @PostDestory:在容器销毁bean之前通知我们进行清理工作
 *
 * 4、BeanPostProcessor[interface]: bean的后置处理器
 *          在bean初始化前进行一些处理工作
 *          postProcessBeforeInitialization:初始化前工作
 *          postProcessAfterInitialization: 初始化之后
 *
 * Spring底层对BeanPostProcessor的使用
 *      bean赋值，注入其他组件 @Autowired 生命周期注解功能，@Async xxxBeanPostProcessor
 * @author gcq
 * @Create 2020-09-22
 */
@ComponentScan("com.atguigu.bean")
@Configuration
public class MainConfigOfLifeCycle {

   // @Scope("prototype")
    @Bean(initMethod = "init",destroyMethod = "detory")
    public Car car() {
        return new Car();
    }
}